package com.ppt;

import com.aspose.slides.License;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
import com.ppt.model.NumVo;
import com.ppt.model.PptData;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author 测试类
 */
public class Main {

	public static void main(String[] args) throws Exception {
		PptDataConverter converter = new PptDataConverter(genData(), "file/template.pptx");//读取模板并填充数据
		converter.outputToFile("file/output.pptx");//输出到文件
		pptx2pdf("file/output.pptx",  "file/output.pdf");
		pptx2html("file/output.pptx", "file/output.html");
		//converter.outputToStream();//输出到文件流(可用于下载)
	}

	public static boolean getLicense() {
		boolean result = false;
		try {
			String license =
					"<License>\n" +
							"  <Data>\n" +
							"    <Products>\n" +
							"      <Product>Aspose.Total for Java</Product>\n" +
							"      <Product>Aspose.Words for Java</Product>\n" +
							"    </Products>\n" +
							"    <EditionType>Enterprise</EditionType>\n" +
							"    <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +
							"    <LicenseExpiry>20991231</LicenseExpiry>\n" +
							"    <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +
							"  </Data>\n" +
							"  <Signature>111</Signature>\n" +
							"</License>";
			InputStream is = new ByteArrayInputStream(license.getBytes(StandardCharsets.UTF_8));
			License asposeLic = new License();
			asposeLic.setLicense(is);
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static void pptx2pdf(String inPath, String outPath) {
		if (!getLicense()) {
			return;
		}
		Presentation pres = new Presentation(inPath);
		try {
			pres.save(outPath, SaveFormat.Pdf);
		} finally {
			pres.dispose();
		}
	}

	public static void pptx2html(String inPath, String outPath) {
		if (!getLicense()) {
			return;
		}
		Presentation pres = new Presentation(inPath);
		try {
			pres.save(outPath, SaveFormat.Html);
		} finally {
			pres.dispose();
		}
	}


	//填充数据
	private static PptData genData() {
		PptData data = new PptData();
		data.setName("张先生");//姓名
		data.setTime("2022年8月");//日期
		//////////家庭财务需求/////////////
		data.setRequirements(Arrays.asList("厘清家庭资产负债现状", "子女教育规划", "养老规划", "构建家庭保障体系", "希望资产每年实现8%-10%的增值"));//家庭财务需求
		List<List<String>> familyMembers = new ArrayList<>();
		familyMembers.add(Arrays.asList("本人", "1982.9.5", "40", "男", "2042年"));
		familyMembers.add(Arrays.asList("配偶", "1983.3.10", "39", "女", "2042年"));
		data.setFamilyMembers(familyMembers);//家庭成员信息表 [姓名/出生日期/年龄/性别/退休或留学年份]
		List<NumVo> propertys = new ArrayList<>();
		propertys.add(new NumVo("流动资金", "活期存款", 100.0));
		propertys.add(new NumVo("流动资金", "银行理财（≤3个月）", 50.0));
		propertys.add(new NumVo("金融资产", "股票", 250.0));
		propertys.add(new NumVo("金融资产", "公募基金", 150.0));
		propertys.add(new NumVo("金融资产", "私募基金", 400.0));
		propertys.add(new NumVo("固定资产（自住）", "自住房", 800.0));
		propertys.add(new NumVo("固定资产（自住）", "自住车位", 30.0));
		propertys.add(new NumVo("固定资产（投资）", "投资住宅1", 300.0));
		propertys.add(new NumVo("固定资产（投资）", "投资公寓1", 200.0));
		propertys.add(new NumVo("固定资产（投资）", "投资公寓2", 200.5));
		propertys.add(new NumVo("固定资产（投资）", "投资商铺", 1502.0));
		propertys.add(new NumVo("公司股权", "公司股权（非参与经营）", 50.0));
		propertys.add(new NumVo("其他资产", "机动车", 50.0));
		data.setPropertys(propertys);//资产负债表-资产
		List<NumVo> debts = new ArrayList<>();
		debts.add(new NumVo("投资住宅房贷", 70.0));
		debts.add(new NumVo("投资公寓房贷", 80.0));
		debts.add(new NumVo("车贷", 20.0));
		data.setDebts(debts);//资产负债表-负债
		List<NumVo> incomes = new ArrayList<>();
		incomes.add(new NumVo("工作性收入", "本人收入", 150.0));
		incomes.add(new NumVo("工作性收入", "配偶收入", 50.0));
		incomes.add(new NumVo("固定资产\r租金收入", "投资住宅租金", 3.0));
		incomes.add(new NumVo("固定资产\r租金收入", "投资公寓租金", 3.5));
		incomes.add(new NumVo("固定资产\r租金收入", "投资商铺金", 3.0));
		incomes.add(new NumVo("金融资产投资收益", "股票", 7.0));
		incomes.add(new NumVo("金融资产投资收益", "公募基金", 2.0));
		incomes.add(new NumVo("金融资产投资收益", "私募基金", 15.0));
		incomes.add(new NumVo("企业分红收入", "企业分红收入（非参与经营）", 2.0));
		data.setIncomes(incomes);//收入支出表-收入 (需添加类别)
		List<NumVo> expands = new ArrayList<>();
		expands.add(new NumVo("日常生活支出", 36.0));
		expands.add(new NumVo("子女教育", 20.0));
		expands.add(new NumVo("赡养父母", 5.0));
		expands.add(new NumVo("休闲娱乐", 5.0));
		expands.add(new NumVo("旅游支出", 10.0));
		expands.add(new NumVo("保险支出", 20.0));
		expands.add(new NumVo("住房还贷", 15.0));
		expands.add(new NumVo("车贷还贷", 5.0));
		data.setExpands(expands);//收入支出表-支出

		//////////////财务比率分析////////////////
		List<Double> financialAnalysis = Arrays.asList(15.52, 6.23, 93.77, 51.16, 66.41, 8.42, 30.60);
		data.setFinancialAnalysis(financialAnalysis);//财务分析和诊断(比率) [流动性比率/负债比率/清偿比率/结余比率/投资比率/负债收入比/被动收入比]
		data.setAssetLayout(Arrays.asList(110.0, 130.0, 190.0));//资产配置布局(雷达图) [流动性/防御性/收益性] (基准值皆为100)
		//流动性比率分析
		data.setLiquidityRatio(	"流动性比率反映流动资金的充裕程度，您的家庭年支出为116万，每月支出为9.67万，"
				+ "支出项主要集中在日常生活支出、子女教育、保险支出、住房还贷支出等"
				+ "，此类支出为家庭目前主要支出， 目前家庭流动资金为150万，相当于 15.52个月的家庭支出，一般情况,  有相对稳定收入来源的家庭，保留3-6个月的家庭总支出（约29万-58万），如收入不稳定的家庭，保留6-12个月的家庭总支出（约58万-116万），目前您家庭的流动性比率过高。\n");
		data.setLiquidityRatioAmount(Arrays.asList(180.0, 9.88));//流动性比率分析对应金额 [流动性资金/家庭月支出]
		//负债比率分析
		data.setDebtRatio("负债率比率反映的是家庭综合偿债能力，目前您家庭的负债率为6.23%，处在安全范围内，家庭偿债能力较强。\n");
		data.setDebtRatioAmount(Arrays.asList(95.0, 5.0));//负债比率分析对应金额 [净资产总额/负债总额]
		//清偿比率分析
		data.setDebtServiceRatio("清偿比率反映的是家庭综合偿债能力，目前您家庭的清偿比率为93.77%，清偿比率高，反映家庭没有合理应用应债能力提高个人资产规模，需要进一步优化。\n");
		//结余比率分析
		data.setBalanceRatio("结余比率反映的是家庭综合偿债能力，目前您家庭的结余比率为51.16%，家庭净资产增长能力强。\n");
		data.setBalanceRatioAmount(Arrays.asList(117.0, 120.0));//结余比率分析对应金额 [年结余/年支出]
		//投资比率分析
		data.setInvestmentRatio( "投资比率反映的是家庭通过投资实现财富增长的能力，目前您家庭的结投资比率为66.41%，投资占比过高，投资收益预期增加的同时投资风险也在增大。\n");
		data.setInvestmentRatioAmount(Arrays.asList(33.0, 67.0));//投资比率分析对应金额 [非投资资产/投资资产]
		//负债收入比率分析
		data.setDebtToIncomeRatio( "负债收入比率反映的是家庭当下的债务负荷程度，目前您家庭的负债收入比率为8.42%，家庭能够应付当前的债务。\n");
		data.setDebtToIncomeRatioAmount(Arrays.asList(18.0, 82.0));//负债收入比率分析对应金额 [当年贷款支出/其他支出+结余]
		//被动收入比率分析
		data.setPassiveIncomeRatio("被动收入比率反映的家庭财务自由度，目前您家庭的被动收入比率为30.6%，家庭收入结构中工作性收入占重要部分，离家庭财务自由还有距离。\n");
		data.setPassiveIncomeRatioAmount(Arrays.asList(66.0, 34.0));//被动收入比率分析对应金额 [被动收入覆盖支出/工作收入覆盖支出]
		//小结
		data.setSummaryOfAnalysis("财务比率用于分析家庭财务状况，七大比率的结果代表目前家庭财务整体健康状况，同时让我们清晰家庭财务是否处于合理状态。我们根据健康的财务比率，在未来家庭财务管理中不断优化家庭资产配置，让家庭财务比率持续趋于健康、合理的状态。\n");

		//////////////家庭风险保障分析////////////////
		List<List<String>> familyRiskSituations = new ArrayList<>();
		//家庭成员/是否有社保/人寿险(保额)/人寿险(保费)/重疾险(保额)/重疾险(保费)/年金险(保额)/年金险(保费)/医疗险(保额)/医疗险(保费)/意外险(保额)/意外险(保费)/合计年交保费（元）
		familyRiskSituations.add(Arrays.asList("本人", "是", "20", "15000", "15", "15000", "-", "100", "350", "10", "100", "24450"));
		familyRiskSituations.add(Arrays.asList("配偶", "是", "20", "15000", "15", "15000", "-", "100", "350", "10", "100", "24450"));
		familyRiskSituations.add(Arrays.asList("儿子", "是", "20", "15000", "15", "15000", "-", "100", "350", "10", "100", "24450"));
		familyRiskSituations.add(Arrays.asList("女儿", "是", "20", "15000", "15", "15000", "-", "100", "350", "10", "100", "24450"));
		data.setFamilyRiskSituations(familyRiskSituations);//分析1(家庭风险保障现状)
		//分析2标题
		data.setRiskAnalysisTitle_2( "2、家庭风险保障缺口\n");
		//分析2正文
		data.setRiskAnalysisContent_2("您和您配偶作为家庭主要经济支柱，家人的高品质生活及孩子未来教育支出、养老生活主要依赖您的家庭收入。基于此，现阶段拥有足额的保障对家庭而言十分重要。\n"
				+ "一般情况下，家庭应配备的寿险保额为能覆盖10年日常生活支出+子女教育总费用+一年以上未偿还的贷款，根据您所提供的财务信息，当前家庭需要：36万*10+320万+170万=850万的保障来保证家人的生活品质，目前家庭总保障为20万，寿险保障缺口为850万-20万=830万。\n"
				+ "\n"
				+ "一般情况下，每位家庭成员的重疾保障应为50-100万。目前本人的重疾保额为15万，保障缺口为35万～85万；目前您配偶重疾保额为10万，保障缺口为40万～90万；您儿子的重疾保额为20万，保障缺口为30万～80万；您女儿的重疾保额为20万，保障缺口为30万～80万。\n"
				+ "\n" + "除了寿险及重疾保障外，医疗与意外的保障也均为家庭保障的必备之选！\n");
		//分析3标题
		data.setRiskAnalysisTitle_3("3、家庭成员的保障配比欠合理\n");
		//分析3正文
		data.setRiskAnalysisContent_3("根据您提供的信息，目前家庭的保费支出为20万/年，其中子女的保费支出占比为75%，尤其是子女的年金保费支出为14万，占比家庭年保费支出的70%，家庭成员间的保障配比欠合理。\n" + "\n"
				+ "通常情况下，家庭的保障需求配置应遵循先以下原则：\n" + "（1）先大人后小孩，先保障险种后储蓄险种\n" + "（2）收入高的家庭成员应优先保障，\n"
				+ "（3）险种的配置顺序应为意外险、医疗险、重疾险、人寿险、年金险\n");
		//分析4标题
		data.setRiskAnalysisTitle_4( "4、保费支出合理\n");
		//分析4正文
		data.setRiskAnalysisContent_4( "通常情况下保费支出占家庭收入的10%左右。目前您的家庭保费支出为20万元，占比合理，可根据家庭实际需求适当增加保障。\n");
		//分析5标题
		data.setRiskAnalysisTitle_5(" ");
		//分析5正文
		data.setRiskAnalysisContent_5(" ");
		//分析小结
		data.setSummaryOfRiskAnalysis("保险是家庭财富管理的必选配置，能为家人带来高品质的医疗保障，抵御家庭意外风险，提高家庭抗风险能力。保险还是家庭财富是最理想的保护工具，能规避多种风险，同时在家庭财富传承规划中，是唯一拥有杠杆功能的工具。所以合理有效的保险配置方案能够有效的满足家庭的风险管理、财富安全及财富传承的综合需求\n");

		//////////////资产结构及收支结构分析//////////////////
		//分析1标题
		data.setStructureAnalysisTitle_1( "1、资产结构\n");
		//分析1正文
		data.setStructureAnalysisContent_1( "1）家庭资产流动性欠合理\n"
				+ "在整体家庭资产中，固定资产为1730万，占总资产的63.37%，占比相对较高。住宅、公寓、车位、商铺等固定资产变现能力弱，导致资产的流动性不足，万一发生风险,固定资产变现可能会面临资产折价，从目前的资产结构来讲，存在一定的流动性风险。\n"
				+ "（2）\uF0D8投资类固定资产未能带来合理的租金收入\n" + "在整体家庭资产中，投资类固定资产带来的租金收入过低，限制了家庭整体资产的增值能力，须对此项资产做出合理调整与规划。\n"
				+ "长期看国内房产已逐步回归保值功能，房产在家庭资产中占比将逐步降低，未来投资性固定资产的持有成本将增加，且变现能力减弱。未来除了核心城市核心地段房产或资源性房产有一定的配置价值，其它地区要慎重考虑。对于家庭资产结构来讲是否还要配置房产主要考虑的因素是：\n"
				+ "\n"
				+ "1、是否具有良好的流动性；2、是否能保持长期合理稳定的租售比；3、房产配置在家庭资产中占比是否合理。投资性房产对于您的家庭来说是一笔不小的支出，如果不作大调整，也应该优化该类资产，提升资产质量，或根据家庭未来需求，将现有家庭资产进行合理的资产配置，以提高现有资产的保值、增值能力。\n"
				+ "\n" + "（3）金融资产配置欠合理\n"
				+ "金融资产是未来家庭资产配置的重要方向，就您目前的家庭金融资产占比总投资资产47%，主要分布股票、公募基金、私募基金，近一年此类资产的收入为24万，占家庭投资收入10.19%");
		//分析2标题
		data.setStructureAnalysisTitle_2("2、收入与支出结构\n");
		//分析2正文
		data.setStructureAnalysisContent_2("（1）收入结构欠合理\n"
				+ "当前您的家庭年收入为235.5万元，其中工作收入为200万元，占比84.93%，被动收入为35.5万元，占比15.07%。工作收入占比过高，家庭的收入主要依赖工作收入，意味着家庭高品质生活支出、孩子教育支出及未来的退休养老生活，高度依赖于“人赚钱”，抵御风险能力较弱。\n");
		//小结
		data.setSummaryOfStructureAnalysis(	"家庭资产结构与收入支出结构是家庭财富管理的核心，资产结构是否合理直接影响了家庭资产的安全性，同时也体现了家庭资产配置的合理性、家庭资产保值增值的效率。而收入支出结构的合理性体现了家庭生活保障及抵抗风险的能力，我们要时刻关注家庭的资产结构与收入支出结构，以保证家庭财富与需求处于健康合理状态。\n");

		/////////////////////配置建议///////////////////////
		//建议1标题
		data.setSuggestionsTitle_1("1、流动资金");
		//现阶段家庭重疾险保障需求 [家庭成员/重疾险现有保额（万）/重疾险应配置保额（万)/重疾险建议补充额度（万）]
		List<List<String>> familySeriousDiseaseInsuranceNeeds = new ArrayList<>();
		familySeriousDiseaseInsuranceNeeds.add(Arrays.asList("本人", "15", "50-100", "35-85"));
		familySeriousDiseaseInsuranceNeeds.add(Arrays.asList("配偶", "10", "50-100", "35-85"));
		data.setFamilySeriousDiseaseInsuranceNeeds(familySeriousDiseaseInsuranceNeeds);
		//建议1正文
		data.setSuggestionsContent_1("流动性比率反映流动资金的充裕程度，您的家庭年支出为116万，每月支出为9.67万，支出项主要集中在日常生活支出、子女教育、保险支出、住房还贷支出等，此类支出为家庭目前主要支出， "
				+ "目前家庭流动资金为150万，相当于 15.52个月的储备资金，一般情况,  建议保留3～6个月的流动资金即可，约29万-58万，目前的流动性资金储备过高，过多的资金放在银行或流动性较强的货币基金收益都极低，意味着超额准备的流动资金难以增值，甚至在通胀的蚕食下贬值。建议可把部分闲置资金做进一步的优化选择。\n");
		//建议2标题
		data.setSuggestionsTitle_2("2、家庭风险管理建议");
		//建议2正文
		data.setSuggestionsContent_2("您和您配偶作为家庭的主要经济支柱，家人高品质的生活及孩子未来的教育支出及养老生活主要依赖您的家庭收入，基于此，现阶段拥有足额的保障对家庭而言十分重要。\n"
				+ "通过前面的诊断分析出当年您家庭的寿险缺口为830万，从家庭工作收入情况来看，您的收入占比为75%，建议您补充的寿险额度为830万*75%=623万；您配偶的收入占比为25%，建议您配偶补充的寿险额度为830万*25%=207万，以满足家庭的寿险风险保障。\n"
				+ "除了寿险外，充足的重疾险保障对家庭来说也尤为重要。通常情况下，我们建议每位家庭成员的重疾保障应配置为50-100万。通过前面的分析诊断，当前您的重疾保额为15万，目前您的配偶重疾保额为10万，儿子的重疾保额为20万，女儿的重疾保额为20万，为了满足家庭的重疾保障额度，我们建议家庭补充的重疾险额度如下：");
		//建议3标题
		data.setSuggestionsTitle_3("3、调整资产配置，构建安全合理的资产结构，满足家庭资产的保值增值需求，同时提高理财性收入的稳定性及确定性");
		//建议3正文
		data.setSuggestionsContent_3("（1）投资类固定资产建议"
				+ "家庭总资产中，投资性固定资产占总投资资产50%，占比相对合理，但未能给家庭带来合理的租金收入，建议在合适的机会优化此类资产，配置在核心地段的优质固定资产，以提升租金收益率，或盘活资产配置于效率更高的其他大类资产。\n"
				+ "（2）金融资产建议\n" + "家庭总资产中，金融资产占总投资资产47.06%，在过去2-3年未能给家庭带来理想性的理财收入，收入确定性较弱，建议针对现有的金融资产进行调整与优化。\n"
				+ "家庭财富管理的核心是资产配置，正确的大类资产配置能给家庭带来安全、持续合理的收益以满足家庭的财务需求。但合理有效的资产配置需要拥有专业能力：\n" + "（1）了解家庭风险耐受度的能力；\n"
				+ "（2）对宏观经济周期和大类资产轮动的判断能力；\n" + "（3）对宏观到中观的择时能力；\n" + "（4）对各类核心交易策略的理解能力；\n" + "（5）对资产配置的再平衡能力等。\n"
				+ "因此运用好金融工具做好家庭的金融资产配置满足未来家庭需求，达成财务目标需要依靠专业的顾问团队。根据家庭的现状与未来需求共同制定有效的配置方案，并进行不间断的动态管理。\n"
				+ "就目前家庭的财务情况及未来财务需求，我们将为您的家庭提供专属的配置方案，详见《投资规划》建议");
		//建议4标题
		data.setSuggestionsTitle_4("4、投资建议\n");
		//建议4正文内容 (资产调整建议描述)
		data.setSuggestionsTableDesc_1("根据上述的诊断分析，我们建议您将家庭现有的资产进行部分调整，具体调整如下：\n");
		//资产调整建议 [序号/类别/原金额（万)/保留金额（万）/变动金额（万）/备注]
		List<List<String>> assetAdjustmentSuggestions = new ArrayList<>();
		assetAdjustmentSuggestions.add(Arrays.asList("1", "银行存款", "100", "60", "40", "保留60万足够用于流动资金储备"));
		assetAdjustmentSuggestions.add(Arrays.asList("2", "银行理财", "50", "0", "50", "流动资金储备已充足"));
		data.setAssetAdjustmentSuggestions(assetAdjustmentSuggestions);
		data.setAssetAdjustmentTotalAmount(90.0);//资产调整建议总金额
		//建议4正文内容(年结余规划描述)
		data.setSuggestionsTableDesc_2("目前您家庭的年结余为121.5万，且该年结余较为稳定，建议保留6.5万用于家庭应急支出，剩余的115万用于投资，每年定期投入，直至退休。\n");
		List<List<String>> annualBalancePlanning = new ArrayList<>();
		//年结余规划 [家庭年结余（万）/用于家庭应急支出（万）/用于投资（万）]
		annualBalancePlanning.add(Arrays.asList("121.5", "6.5", "115"));
		data.setAnnualBalancePlanning(annualBalancePlanning);
		data.setSuggestionsTableDesc_3("根据您家庭的财务需求，目前本人年龄为40岁，配偶为39岁，预计1年后（即2023年）需要支付子女的教育费用40万/年，共8年，夫妻俩计划2042年开始退休，退休后的理财生活费用为30万/年，我们将调整出来的资金及家庭年结余做以下投资规划，投资年化收益率为6%-8%，以满足家庭的财务需求。\n"
				+ "预期投资组合收益率为6%：\n");//建议4正文内容(投资规划描述1)
		List<List<String>> investmentPlanning1 = new ArrayList<>();
		for (int i = 0; i < 61; i++) {
			investmentPlanning1.add(Arrays.asList(i + 1 + "", 2022 + i + "", 40 + i + "", "3,900,000.00", "", "3,900,000.00", "",
					"3,900,000.00"));
		}
		//投资规划1 (最多60条) [投资年数/年份/年龄/投资金额/账户价值/子女教育/养老金/账户剩余价值]
		data.setInvestmentPlanning1(investmentPlanning1);
		//建议4正文内容(投资规划总结1)
		data.setSuggestionsTableDesc_4("通过上述表格可以看到，利用6%的投资组合年化收益率演算，在2023年至2030年满足家庭8年两个的子女教育支出及夫妻60岁后每年30万（现值）的养老生活，在您100岁时，投资组合账户剩余28,729万用作传承。\n");

		//建议4正文内容(投资规划描述2)
		data.setSuggestionsTableDesc_5("预期投资组合收益率为8%：\n");
		//投资规划2 (最多60条) [投资年数/年份/年龄/投资金额/账户价值/子女教育/养老金/账户剩余价值]
		data.setInvestmentPlanning2(investmentPlanning1);
		//建议4正文内容(投资规划总结2)
		data.setSuggestionsTableDesc_6("通过上述表格可以看到，利用8%的投资组合年化收益率演算，在2023年至2030年满足家庭8年两个的子女教育支出及夫妻60岁后每年30万（现值）的养老生活，在您100岁时，投资组合账户剩余104,737万用作传承。\n");
		data.setAllocationPlan(""); //配置方案 (理财师自定义增加)
		Map<String, List<Double>> values = new LinkedHashMap<>();
		values.put("工作性收入", Arrays.asList(200.0, 200.0, 200.0));
		values.put("固定资产租金收入", Arrays.asList(9.5, 9.5, 9.5));
		values.put("企业分红收入", Arrays.asList(2.0, 2.0, 2.0));
		values.put("金融资产投资收益", Arrays.asList(24.0, 72.0, 323.0));
		//资产配置前后变化 key=收入类别 value=[配置前金额/配置后第5年金额/配置后第10年金额]
		data.setAssetAllocationChangesBeforeAndAfter(values);

		return data;
	}
}

